package com.lebang.service.task.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.lebang.common.util.AmountUtil;
import com.lebang.common.util.ShowDateUtil;
import com.lebang.component.MultiwordComponent;
import com.lebang.component.RedisClient;
import com.lebang.entity.RequestHeaders;
import com.lebang.entity.member.LbbMember;
import com.lebang.entity.member.LbbMemberRecord;
import com.lebang.entity.task.LbbCommon;
import com.lebang.mapper.LbbMemberRecordMapper;
import com.lebang.mapper.buss.multiword.MultiwordMapper;
import com.lebang.mapper.buss.multiword.MultiwordSpeechMapper;
import com.lebang.mapper.buss.multiword.MultiwordSpeechPlanMapper;
import com.lebang.model.enums.Booleans;
import com.lebang.model.enums.buss.RecordStatus;
import com.lebang.model.enums.buss.TaskCategory;
import com.lebang.model.enums.buss.TaskStatus;
import com.lebang.model.enums.buss.UserStatus;
import com.lebang.model.taskback.CommonCallBack;
import com.lebang.model.taskback.Detail;
import com.lebang.model.taskback.Record;
import com.lebang.model.vo.buss.multiword.Multiword;
import com.lebang.model.vo.buss.multiword.MultiwordSpeech;
import com.lebang.model.vo.buss.multiword.MultiwordSpeechPlan;
import com.lebang.service.MemberNoticeService;
import com.lebang.service.TaskInRedisService;
import com.lebang.service.buss.MemberRecordService;
import com.lebang.service.buss.WalletService;
import com.lebangweb.common.DateUtil;
import com.lebangweb.common.TextUtil;
import com.lebangweb.response.Callback;
import com.lebangweb.response.JsonData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Service("multiwordservice")
public class MultiwordServiceImpl extends CommonServiceImpl {
    private static final String STR = "{text}<div><font color=\"#c24f4a\"></font></div><div><font color=\"#c24f4a\"></font></div><div><font color=\"#c24f4a\">搜索关键词：</font><font color=\"#46acc8\">{name}</font></div><p></p><p><font color=\"#c24f4a\">该应用大概在搜索列表</font><font color=\"#46acc8\">{paiming}</font><font color=\"#c24f4a\">名左右</font></p><p><font color=\"#c24f4a\">认准该应用名字与图标，</font><a href=\"{skip_url}\" target=\"_blank\" style=\"background-color: rgb(255, 255, 255);\">打开！</a></p><p><br></p><p><br></p>";
    private static final Logger log = LoggerFactory.getLogger(MultiwordServiceImpl.class);
    @Autowired
    private MultiwordMapper multiwordMapper;
    @Autowired
    private MultiwordSpeechMapper multiwordSpeechMapper;
    @Autowired
    private MultiwordSpeechPlanMapper multiwordSpeechPlanMapper;
    @Autowired
    private RedisClient redisClient;
    @Autowired
    private MultiwordComponent multiwordComponent;
    @Autowired
    private MemberRecordService memberRecordService;
    @Autowired
    private WalletService walletService;
    @Autowired
    private TaskInRedisService taskInRedisService;

    @Autowired
    private MemberNoticeService memberNoticeService;
    public static final String TASK_MULTIWORD_AMOUNT = "task_multiword_amount";
    @Autowired
    private LbbMemberRecordMapper lbbMemberRecordMapper;



    public Multiword selectByPrimaryKey(Long id) {
        return multiwordMapper.selectByPrimaryKey(id);
    }

    public MultiwordSpeech getMultiwordSpeechById(String orderId) {
        return multiwordSpeechMapper.selectByPrimaryKey(Long.parseLong(orderId));
    }

    public MultiwordSpeechPlan getMultiwordSpeechplanById(int orderId) {
        return multiwordSpeechPlanMapper.selectByPrimaryKey(orderId);
    }

    public int updateMultiwordSpeech(MultiwordSpeech multiwordSpeech) {
        return multiwordSpeechMapper.updateByPrimaryKeySelective(multiwordSpeech);
    }

    public MultiwordSpeech getMultiwordSpeechById(Long orderId) {
        return multiwordSpeechMapper.selectByPrimaryKey(orderId);
    }

    public MultiwordSpeechPlan getmultiwordSpeech(Long id, String str) {
        return multiwordSpeechPlanMapper.getmultiwordSpeech(id, str);
    }


    public int updateMultiwordSpeechPlain(MultiwordSpeechPlan plan) {
        return multiwordSpeechPlanMapper.updateByPrimaryKeySelective(plan);
    }

    public JsonData editMultiwordSpeech(MultiwordSpeech item) {
        try {
            item.setModifyTime(new Date());
            int i = 0;
            if (item.getId() != null) {
                i = multiwordSpeechMapper.updateByPrimaryKeySelective1(item);
            } else {
                item.setCreateTime(new Date());
                item.setAllTotal(0);
                item.setTadayTotal(0);
                item.setHasPlan(0);
                item.setRevision(0);
                i = multiwordSpeechMapper.insertSelective(item);
            }
            if (i > 0) {
                return Callback.success("200", "操作成功", null);
            } else {
                return Callback.fail("200", "操作失败", null);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Callback.fail("200", "网络异常", e);
        }

    }

    public JsonData editMultiwordSpeechplan(MultiwordSpeechPlan item) {
        try {
            if (item.getAmount() <= 0) {
                return Callback.fail("200", "每日量必须大于0", null);
            }

            int i = 0;
            item.setModifyTime(new Date());
            int count = multiwordSpeechPlanMapper.selectByruntime(item);
            if (count > 0) {
                return Callback.fail("200", "执行计划" + item.getRunTime() + "已存在!", null);
            }
            if (item.getId() != null) {


                i = multiwordSpeechPlanMapper.updateByPrimaryKeySelective(item);
            } else {
                item.setCreateTime(new Date());
                item.setTadayTotal(0);

                i = multiwordSpeechPlanMapper.insertSelective(item);
            }
            if (i > 0) {
                int u = multiwordSpeechMapper.findhasplan(item.getMultiwordSpeechId());
                MultiwordSpeech m = new MultiwordSpeech();
                m.setId(Long.parseLong(item.getMultiwordSpeechId().toString()));
                if (u > 0) {
                    m.setHasPlan(1);
                } else {
                    m.setHasPlan(0);
                }
                multiwordSpeechMapper.updateByPrimaryKeySelective1(m);
                return Callback.success("200", "操作成功", null);
            } else {
                return Callback.fail("200", "操作失败", null);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Callback.fail("200", "网络异常", e);
        }

    }

    public JsonData speechdelete(Integer id) {
        try {
            int i = multiwordSpeechMapper.speechdelete(id);
            if (i > 0) {
                redisClient.hdel(TASK_MULTIWORD_AMOUNT, id.toString());
                return Callback.success("200", "操作成功", null);
            } else {
                return Callback.fail("200", "操作失败", null);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Callback.fail("200", "网络异常", e);
        }
    }

    public JsonData speechplandelete(Integer id) {
        try {
            int i = multiwordSpeechPlanMapper.speechplandelete(id);
            MultiwordSpeechPlan multiwordSpeechPlan = multiwordSpeechPlanMapper.selectByPrimaryKey(id);
            if (i > 0) {
                int u = multiwordSpeechMapper.findhasplan(id);
                MultiwordSpeech m = new MultiwordSpeech();
                m.setId(Long.parseLong((multiwordSpeechPlan.getMultiwordSpeechId().toString())));
                if (u > 0) {
                    m.setHasPlan(1);
                } else {
                    m.setHasPlan(0);
                }
                multiwordSpeechMapper.updateByPrimaryKeySelective1(m);
                return Callback.success("200", "操作成功", null);
            } else {
                return Callback.fail("200", "操作失败", null);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Callback.fail("200", "网络异常", e);
        }
    }


    @Override
    public RecordStatus pull(String memberId, LbbCommon task, RequestHeaders requsetHeader, String orderid,String taskId) {
        try {
            Long multiwordSpeedId = multiwordComponent.findSumAmount(task.getId());
            String userid = requsetHeader.getUserid();
            userid = userid == null ? "" : userid;

            // 获取任务量完成情况
            Integer o = taskInRedisService.getTaskAmount(TASK_MULTIWORD_AMOUNT, multiwordSpeedId.toString());
            if (o <= 0) {
                return RecordStatus.OUT_OF_STOCK;
            }
            // 用户是否做过
            LbbMemberRecord record = memberRecordService.checkRecord(userid, task.getTaskId(), TaskCategory.Common.name());
            if (record != null) {
                return RecordStatus.EXIST;
            }
            MultiwordSpeech multiwordSpeech = this.getMultiwordSpeechById(multiwordSpeedId);
            List<String> stringList = Arrays.asList(multiwordSpeech.getIcoUrl().split(","));
            int index = 1;
            List<Map<String, Object>> mapList = new ArrayList<>(1);
            for (String s : stringList) {
                Map<String, Object> map = new HashMap<>(1);
                Map<String, Object> map1 = new HashMap<>(1);
                if (index == 1) {
                    String s1 = STR.replace("{name}", multiwordSpeech.getName());
                    s1 = s1.replace("{paiming}", multiwordSpeech.getRanking().toString());
                    s1 = s1.replace("{skip_url}", multiwordSpeech.getSkipUrl());
                    s1 = s1.replace("{text}", task.getContents());
                    map.put("text", s1);
                    map.put("type", "image");
                    map1.put("image", s);
                    map1.put("title", "图例" + index);
                    map.put("image", map1);
                    mapList.add(map);
                } else {
                    map.put("text", "<p></p>");
                    map.put("type", "image");
                    map1.put("image", s);
                    map1.put("title", "图例" + index);
                    map.put("image", map1);
                    mapList.add(map);
                }
                index++;
            }

            int i = memberRecordService.insertRecord(TaskCategory.Common, task.getTaskId(), memberId, requsetHeader,
                    TaskStatus.WaitSumbit, JSON.toJSONString(mapList), Long.toString(multiwordSpeedId),
                    Booleans.True, 0, AmountUtil.checkAmount(task),task.getIncrease(),task.getType() ,task.getTitle());
            taskInRedisService.taskAmountSubtract(TASK_MULTIWORD_AMOUNT, multiwordSpeech.getId().toString());
            taskInRedisService.recordAdd(i);
            return RecordStatus.PULL_SUCCESS;
        } catch (Exception e) {
            e.printStackTrace();
            return RecordStatus.ERROR;
        }
    }

    @Override
    public RecordStatus push(String memberId, LbbMemberRecord record2, LbbCommon task, String result, Integer sex) {
        try {
            // 用户是否领取
            LbbMemberRecord record = memberRecordService.checkRecord(memberId, task.getTaskId(), TaskCategory.Common.name());
            if (record == null) {
                return RecordStatus.EMPTY;
            }
            if (sex != null) {
                record.setSex(sex);
            }
            // 任务是否是待提交
            if (!TaskStatus.WaitSumbit.equals(record.getStatus())) {
                return RecordStatus.EXIST;
            }
            if (null == result || "".equals(result)) {
                return RecordStatus.FAIL;
            } else {
                record.setResult(result);
                record.setSubmitTime(new Date());
                record.setStatus(TaskStatus.WaitCheckout);
                memberRecordService.updateByPrimaryKeySelective(record);
                String desc = "恭喜！任务“{title}”已提交，小姐姐正在努力审核!";
                desc = desc.replace("{title}", task.getTitle());
                memberNoticeService.notice(record, TaskCategory.Common.getTitle(), desc);
                if (record.getRedo() != null) {
                    if (record.getRedo() == 0) {
                        taskInRedisService.recordDel(record.getId());
                    }
                }
                return RecordStatus.PUSH_SUCCESS;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return RecordStatus.ERROR;
        }
    }

    @Override
    public CommonCallBack taskDetail(LbbCommon task, LbbMemberRecord record, LbbMember member, String orderId) throws Exception {
        CommonCallBack commonCallBack = new CommonCallBack();
        Record reco = new Record();
        Detail detail = new Detail();
        Long multiSpeechId;
        if (record == null) {
            multiSpeechId = multiwordComponent.findSumAmount(task.getId());
        } else {
            multiSpeechId = Long.parseLong(record.getOrderId());
        }
        String userStatus = UserStatus.Allow.name();
        // 如果做过不允许再做
        MultiwordSpeech multiwordSpeech1 = this.getMultiwordSpeechById(multiSpeechId);
        List<String> stringList = Arrays.asList(multiwordSpeech1.getIcoUrl().split(","));
        int index = 1;
        List<Map<String, Object>> mapList = new ArrayList<>(1);
        for (String s : stringList) {
            Map<String, Object> map = new HashMap<>(1);
            Map<String, Object> map1 = new HashMap<>(1);
            if (index == 1) {
                String s1 = STR.replace("{name}", multiwordSpeech1.getName());
                s1 = s1.replace("{paiming}", multiwordSpeech1.getRanking().toString());
                s1 = s1.replace("{skip_url}", multiwordSpeech1.getSkipUrl());
                s1 = s1.replace("{text}", task.getContents());
                map.put("text", s1);
                map.put("type", "image");
                map1.put("image", s);
                map1.put("title", "图例" + index);
                map.put("image", map1);
                mapList.add(map);
            } else {
                map.put("text", "<p></p>");
                map.put("type", "image");
                map1.put("image", s);
                map1.put("title", "图例" + index);
                map.put("image", map1);
                mapList.add(map);
            }
            index++;
        }
        detail.setContents(mapList);
        if (record != null) {
            // 如果做过不允许再做
            commonCallBack.setCreatTime(DateUtil.dateToString(record.getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
            userStatus = UserStatus.Disallow.name();
            if (!record.getStatus().equals(TaskStatus.WaitSumbit)) {
                commonCallBack.setMemberResult(JSONArray.parseArray(record.getResult()));
            } else {
                record.setResult("");
            }
            commonCallBack.setType(record.getRewordType());
            commonCallBack.setUserMoney(record.getUserMoney());
        } else {
            record = new LbbMemberRecord();
            record.setCreateTime(new Date());
            record.setStatus(TaskStatus.None);
            commonCallBack.setUserMoney(AmountUtil.checkAmount(task));
            commonCallBack.setType(task.getType().getIndex());
        }
        if (TextUtil.isEmpty(task.getPkg())) {
            detail.setPackagename("");
        } else {
            detail.setPackagename(task.getPkg());
        }
        detail.setIsMultiword(true);
        detail.setPkg(task.getPkg());
        detail.setAmount(multiwordComponent.getAmountById(task.getId()));
        detail.setIcon(task.getIcon());
        detail.setTitle(task.getTitle());
        detail.setLabel(task.getLabel());
        detail.setType(task.getType());
        detail.setMedia(task.getMedia());
        detail.setUserStatus(userStatus);
        detail.setOrderid(multiSpeechId.toString());
        reco.setEndTime(ShowDateUtil.afterMinute(record.getCreateTime(), 30));
        reco.setStatus(record.getStatus().name());
        reco.setRemark(record.getRemark());
        reco.setResult(record.getResult() == null ? "" : record.getResult());
        reco.setSubmitTime(record.getSubmitTime() == null ? "" : DateUtil.dateToString(record.getSubmitTime(), "yyyy-MM-dd HH:mm:ss"));
        commonCallBack.setCategory(TaskCategory.Common.name());
        commonCallBack.setTaskid(task.getTaskId());
        commonCallBack.setTaskTime(task.getTaskTime());
        commonCallBack.setAuditTime(task.getAuditTime());
        commonCallBack.setRedoStatus(task.getRedo());
        if (task.getRedo() == null) {
            task.setRedo(0);
        }
        if (record.getHurryTime() == null) {
            commonCallBack.setHurryTime(0);
        } else {
            commonCallBack.setHurryTime(1);
        }
        if (record.getRedo() == null) {
            record.setRedo(0);
        }
        if (record.getSubmitTime() != null && record.getCreateTime() != null) {
            commonCallBack.setOverTime(ShowDateUtil.getDatePoor(record.getSubmitTime(), record.getCreateTime()));
        } else {
            commonCallBack.setOverTime("0");
        }
        commonCallBack.setRedocount(record.getRedo());
        commonCallBack.setRecord(reco);
        commonCallBack.setDetail(detail);
        return commonCallBack;
    }

    @Override
    public boolean starTaskAmount(LocalDateTime dateTime) {
        try {
            redisClient.del(TASK_MULTIWORD_AMOUNT);
            List<MultiwordSpeech> msList = multiwordSpeechMapper.getMultiwordSpeechAll();
            this.starTask(msList,dateTime);
            log.info("加载多词每日量任务到redis中成功");
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public void releaseTask(LbbMemberRecord record) {
        LbbCommon lbbCommon = lbbCommonMapper.getByTaskId(record.getTaskId());
        String date = DateUtil.dateToString(new Date(), "yyyyMMdd");
        String creatdate = DateUtil.dateToString(record.getCreateTime(), "yyyyMMdd");
        //修改释放任务方法的判断避免多次释放任务.释放多词任务后若是当天释放则将数量补充进池中.
        if (date.equals(creatdate)) {
            taskInRedisService.taskAmountAdd(TASK_MULTIWORD_AMOUNT, record.getOrderId());
        }
        String title = "通用任务释放通知";
        String desc = "任务通知【" + lbbCommon.getTitle() + "】未在规定时间内完成,已被释放,请重新领取!";
        memberNoticeService.notice(record, title, desc);
    }

    private boolean starTask(List<MultiwordSpeech> msList,LocalDateTime dateTime) {
        DateTimeFormatter formatter=DateTimeFormatter.ofPattern("yyyyMMdd");
        String datestr = dateTime.toLocalDate().format(formatter);
        for (MultiwordSpeech item : msList) {
            int count=0;
            if ( item.getAmount() == 0) {
                item.setAmount(99999);
            }
            if (item.getTotal() == 0 ) {
                item.setTotal(999999);
            }
            if (item.getHasPlan() == 0) {
                if (item.getAllTotal() >= item.getTotal()) {
                } else {
                    if (item.getTotal() - item.getAllTotal() >= item.getAmount()) {
                        count = item.getAmount();
                    } else {
                         count = item.getTotal() - item.getAllTotal();
                    }
                }

            } else {
                /**有执行计划**/
                MultiwordSpeechPlan multiwordSpeechPlan = multiwordSpeechPlanMapper.getmultiwordSpeech(item.getId(), datestr);
                if (multiwordSpeechPlan != null) {
                    item.setAmount(multiwordSpeechPlan.getAmount());
                    if (item.getAllTotal() >= item.getTotal()) {
                        count = 0;
                    } else {
                        if (item.getTotal() - item.getAllTotal() >= item.getAmount()) {
                            count = item.getAmount();
                        } else {
                            count = item.getTotal() - item.getAllTotal();
                        }
                    }
                }
            }
            String taskId = lbbCommonMapper.selectByPrimaryKey(item.getMultiwordId()).getTaskId();
            int o = lbbMemberRecordMapper.getWaitSubitAndOrderId(LocalDateTime.of(dateTime.toLocalDate(), LocalTime.MIN),LocalDateTime.of(dateTime.toLocalDate(), LocalTime.MAX), taskId,item.getId().toString());
            count = count - o;
            if (count < 0) {
                count = 0;
            }
            redisClient.hset(TASK_MULTIWORD_AMOUNT, item.getId().toString(), String.valueOf(count));
        }
        return true;
    }

    public boolean startaskamountr(List<MultiwordSpeech> commons) {
        return this.starTask(commons,LocalDateTime.now());
    }

    public List<MultiwordSpeech> getMultiwordSpeech(Long id) {
        return multiwordSpeechMapper.getMultiwordSpeech(id);
    }


}
